﻿using BL_Client.ServiceReference1;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BL_Client
{
    public class BL : IBL
    {
        ServiceReference1.IBL ws;

        public BL()
        {
            ws = new ServiceReference1.BLClient("BasicHttpBinding_IBL");
        }

        #region Cities
        public bool AddCity(ServiceReference1.City city)
        {
            return ws.AddCity(city);
        }

        public IEnumerable<ServiceReference1.City> GetAllCities()
        {
            return ws.GetAllCities().ToList();
        }

        public IEnumerable<ServiceReference1.City> GetCities(int startIndex, int count, string sorting)
        {
            IEnumerable<City> query = ws.GetAllCities();

            //Sorting
            //This ugly code is used just for demonstration.
            //Normally, Incoming sorting text can be directly appended to an SQL query.
            if (string.IsNullOrEmpty(sorting) || sorting.Equals("Name ASC"))
            {
                query = query.OrderBy(p => p.Name);
            }
            else if (sorting.Equals("Name DESC"))
            {
                query = query.OrderByDescending(p => p.Name);
            }
            else
            {
                query = query.OrderBy(p => p.Name); //Default!
            }

            return count > 0
                       ? query.Skip(startIndex).Take(count).ToList() //Paging
                       : query.ToList(); //No paging
        }

        public bool RemoveCity(int id)
        {
            return ws.RemoveCity(id);
        }

        public bool UpdateCity(ServiceReference1.City city)
        {
            return ws.UpdateCity(city);
        }
        #endregion

        #region Programs
        public IEnumerable<Program> GetAllPrograms()
        {
            return ws.GetAllPrograms().ToList();
        }

        public bool AddProgram(Program program)
        {
            return ws.AddProgram(program);
        }

        public bool RemoveProgram(int id)
        {
            return ws.RemoveProgram(id);
        }

        public bool UpdateProgram(Program program)
        {
            return ws.UpdateProgram(program);
        }
        #endregion

        #region Professions
        public IEnumerable<ServiceReference1.Profession> GetAllProfessions()
        {
            return ws.GetAllProfessions().ToList();
        }

        public bool AddProfession(ServiceReference1.Profession profession)
        {
            return ws.AddProfession(profession);
        }

        public bool RemoveProfession(int ID)
        {
            return ws.RemoveProfession(ID);
        }

        public bool UpdateProfession(ServiceReference1.Profession profession)
        {
            return ws.UpdateProfession(profession);
        }
        #endregion

        #region Dorms
        public IEnumerable<ServiceReference1.Dorm> GetAllDorms()
        {
            return ws.GetAllDorms().ToList();
        }

        public bool AddDorm(ServiceReference1.Dorm dorm)
        {
            return ws.AddDorm(dorm);
        }

        public bool RemoveDorm(int ID)
        {
            return ws.RemoveDorm(ID);
        }

        public bool UpdateDorm(ServiceReference1.Dorm dorm)
        {
            return ws.UpdateDorm(dorm);
        }
        #endregion

        #region Rooms
        public IEnumerable<Room> GetAllRooms()
        {
            return ws.GetAllRooms();
        }

        public bool AddRoom(Room room)
        {
            return ws.AddRoom(room);
        }

        public bool RemoveRoom(int id)
        {
            return ws.RemoveRoom(id);
        }

        public bool UpdateRoom(Room room)
        {
            room.Charge = ws.GetAllCharges().Where(c => c.ID == room.ChargeID).Single();
            room.Dorm = ws.GetAllDorms().Where(d => d.ID == room.DormID).Single();

            return ws.UpdateRoom(room);
        }
        #endregion

        #region Charges
        public IEnumerable<Charge> GetAllCharges()
        {
            return ws.GetAllCharges();
        }

        public bool AddCharge(Charge charge)
        {
            return ws.AddCharge(charge);
        }

        public bool RemoveCharge(int id)
        {
            return ws.RemoveCharge(id);
        }

        public bool UpdateCharge(Charge charge)
        {
            return ws.UpdateCharge(charge);
        }
        #endregion

        #region Students
        public IEnumerable<Student> GetAllStudents()
        {
            return ws.GetAllStudents();
        }

        public IEnumerable<Student> GetStudents(int startIndex, int count, string sorting)
        {
            IEnumerable<Student> query = ws.GetAllStudents();

            //Sorting
            //This ugly code is used just for demonstration.
            //Normally, Incoming sorting text can be directly appended to an SQL query.
            if (string.IsNullOrEmpty(sorting) || sorting.Equals("FirstName ASC"))
            {
                query = query.OrderBy(s => s.FirstName);
            }
            else if (sorting.Equals("FirstName DESC"))
            {
                query = query.OrderByDescending(s => s.FirstName);
            }
            else if (sorting.Equals("LastName ASC"))
            {
                query = query.OrderBy(s => s.LastName);
            }
            else if (sorting.Equals("LastName DESC"))
            {
                query = query.OrderByDescending(s => s.LastName);
            }
            else if (sorting.Equals("CityID ASC"))
            {
                query = query.OrderBy(s => s.City.Name);
            }
            else if (sorting.Equals("CityID DESC"))
            {
                query = query.OrderByDescending(s => s.City.Name);
            }
            else if (sorting.Equals("ProgramID ASC"))
            {
                query = query.OrderBy(s => s.Program.Name);
            }
            else if (sorting.Equals("ProgramID DESC"))
            {
                query = query.OrderByDescending(s => s.Program.Name);
            }
            else if (sorting.Equals("ProfessionID ASC"))
            {
                query = query.OrderBy(s => s.Profession.Name);
            }
            else if (sorting.Equals("ProfessionID DESC"))
            {
                query = query.OrderByDescending(s => s.Profession.Name);
            }
            else
            {
                query = query.OrderBy(s => s.FirstName); //Default!
            }

            return count > 0
                       ? query.Skip(startIndex).Take(count).ToList() //Paging
                       : query.ToList(); //No paging
        }

        public IEnumerable<Student> GetStudentsByFilter(string firstname, string lastname, int cityId, int startIndex, int pageSize, string sorting)
        {
            IEnumerable<Student> query = ws.GetAllStudents();

            //Filters
            if (!string.IsNullOrEmpty(firstname))
            {
                query = query.Where(s => s.FirstName.IndexOf(firstname, StringComparison.OrdinalIgnoreCase) >= 0);
            }

            if (!string.IsNullOrEmpty(lastname))
            {
                query = query.Where(s => s.LastName.IndexOf(lastname, StringComparison.OrdinalIgnoreCase) >= 0);
            }

            if (cityId > 0)
            {
                query = query.Where(s => s.CityID == cityId);
            }

            //Sorting
            //This ugly code is used just for demonstration.
            //Normally, Incoming sorting text can be directly appended to an SQL query.
            if (string.IsNullOrEmpty(sorting) || sorting.Equals("FirstName ASC"))
            {
                query = query.OrderBy(s => s.FirstName);
            }
            else if (sorting.Equals("FirstName DESC"))
            {
                query = query.OrderByDescending(s => s.FirstName);
            }
            else if (sorting.Equals("LastName ASC"))
            {
                query = query.OrderBy(s => s.LastName);
            }
            else if (sorting.Equals("LastName DESC"))
            {
                query = query.OrderByDescending(s => s.LastName);
            }
            else if (sorting.Equals("CityID ASC"))
            {
                query = query.OrderBy(s => s.City.Name);
            }
            else if (sorting.Equals("CityID DESC"))
            {
                query = query.OrderByDescending(s => s.City.Name);
            }
            else if (sorting.Equals("ProgramID ASC"))
            {
                query = query.OrderBy(s => s.Program.Name);
            }
            else if (sorting.Equals("ProgramID DESC"))
            {
                query = query.OrderByDescending(s => s.Program.Name);
            }
            else if (sorting.Equals("ProfessionID ASC"))
            {
                query = query.OrderBy(s => s.Profession.Name);
            }
            else if (sorting.Equals("ProfessionID DESC"))
            {
                query = query.OrderByDescending(s => s.Profession.Name);
            }
            else
            {
                query = query.OrderBy(s => s.FirstName); //Default!
            }

            return pageSize > 0
                       ? query.Skip(startIndex).Take(pageSize).ToList() //Paging
                       : query.ToList(); //No paging
        }

        public bool AddStudent(Student student)
        {
            return ws.AddStudent(student);
        }

        public bool RemoveStudent(int id)
        {
            return ws.RemoveStudent(id);
        }

        public bool UpdateStudent(Student student)
        {
            return ws.UpdateStudent(student);
        }
        #endregion

        #region Placements
        public IEnumerable<Placement> GetAllPlacements()
        {
            return ws.GetAllPlacements().ToList();
        }

        public bool AddPlacement(Placement placement)
        {
            return ws.AddPlacement(placement);
        }

        public bool RemovePlacement(int id)
        {
            return ws.RemovePlacement(id);
        }

        public bool UpdatePlacement(Placement placement)
        {
            return ws.UpdatePlacement(placement);
        }
        #endregion

        #region Users
        public IEnumerable<User> GetAllUsers()
        {
            return ws.GetAllUsers();
        }

        public bool AddUser(User user)
        {
            return ws.AddUser(user);
        }

        public bool RemoveUser(int id)
        {
            return ws.RemoveUser(id);
        }

        public bool UpdateUser(User user)
        {
            return ws.UpdateUser(user);
        }

        public User GetUserByID(int id)
        {
            return ws.GetUserByID(id);
        }

        public User GetUserByEmail(string email)
        {
            return ws.GetUserByEmail(email);
        }
        #endregion

        #region User Resistration
        public User LoginUser(string email, string password)
        {
            User user = ws.GetUserByEmail(email);

            if (user != null && user.Password == password)
            {
                return user;
            }

            return null;
        }
        #endregion
    }
}
